﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using DataProcessor.Core;

namespace DataProcessor.FashionData
{
    public class UmapProcessor
    {
        public static void Run()
        {
            var up = new UmapProcessor();
            //up.CompareExpertAndNoneExpertGT(@"D:\Data\Dropbox\University\Fashion10000\HIT Result\Processed\200Batch_MajorityVoting.csv",
            //    @"D:\Data\Dropbox\University\Mediaeval 2013\Submissions\GT\Test20_GT.csv",
            //    @"D:\Data\Dropbox\University\Fashion10000\HIT Result\Processed\200CompareWithGtLuke.csv");

            //up.FindDiffAndMerge(@"D:\Data\Dropbox\University\UMAP 2014\New Runs\Jonathon\T_MV\0.csv",
            //    @"D:\Data\Dropbox\University\Mediaeval 2013\Submissions\GT\Test20_MV.csv",
            //    @"D:\Data\Dropbox\University\UMAP 2014\New Runs\JonMvDiffWithMv.csv");


            up.CompareDifferencesWithMv(@"D:\Data\Dropbox\University\Fashion10000\HIT Result\Processed\200CompareWithGtLuke.csv",
                @"D:\Data\Dropbox\University\Mediaeval 2013\Submissions\GT\Test20_Mv.csv",
                @"D:\Data\Dropbox\University\Fashion10000\HIT Result\Processed\200Batch_PerImage_Experts.csv",
                @"D:\Data\Dropbox\University\Fashion10000\HIT Result\Processed\200CompareAll.csv");
        }

        // This method compare the ground truth that is generated by authors of UMAP with the one generated by Luke
        // The comparison is on the subset of 200 images of the Fashion10000 test set (contains 6K+ image)
        public void CompareExpertAndNoneExpertGT(string expertFile, string nonExpertFile, string outputFile)
        {
            var experts = File.ReadAllLines(expertFile).ToCsvDictionary()
                .Select(i => new { Url = i["PictureURL"], Label1 = i["Q1_Majority"], Label2 = i["Q2_Majority"] });

            var nonExperts = File.ReadAllLines(nonExpertFile).Select(l => 
            {
                var parts = l.Split(',');
                return new { Url = parts[0], Label1 = parts[1], Label2 = parts[2] };
            });

            var output = experts.Join(nonExperts, e => e.Url, ne => ne.Url, (e, ne) =>
                new { Url = e.Url, Label1E = e.Label1, Label2E = e.Label2, Label1NE = ne.Label1, Label2NE = ne.Label2 })
                .Where(i => !String.Equals(i.Label1E.ToLower(), i.Label1NE.ToLower()) || !String.Equals(i.Label2E.ToLower(), i.Label2NE.ToLower()))
                .Select(i => string.Format("{0},{1},{2},{3},{4}", i.Url, i.Label1E, i.Label1NE, i.Label2E, i.Label2NE));

            var header = new string[] { "Url,Label1E,Label1NE,Label2E,Label2NE" };
            File.WriteAllLines(outputFile, header.Concat(output));
        }

        public void FindDiffAndMerge(string file1, string file2, string outputFile)
        {
            var rec1 = File.ReadAllLines(file1).Select(l =>
            {
                var parts = l.Split(',');
                return new { Url = parts[0], Label1 = parts[1], Label2 = parts[2] };
            });

            var rec2 = File.ReadAllLines(file2).Select(l =>
            {
                var parts = l.Split(',');
                return new { Url = parts[0], Label1 = parts[1], Label2 = parts[2] };
            });

            var output = rec1.Join(rec2, e => e.Url, ne => ne.Url, (e, ne) =>
                new { Url = e.Url, Label1E = e.Label1, Label2E = e.Label2, Label1NE = ne.Label1, Label2NE = ne.Label2 })
                .Where(i => !String.Equals(i.Label1E.ToLower(), i.Label1NE.ToLower()) || !String.Equals(i.Label2E.ToLower(), i.Label2NE.ToLower()))
                .Select(i => string.Format("{0},{1},{2},{3},{4}", i.Url, i.Label1E, i.Label1NE, i.Label2E, i.Label2NE));

            var header = new string[] { "Url,Label1_1,Label1_2,Label2_1,Label2_2" };
            File.WriteAllLines(outputFile, header.Concat(output));
        }


        // This method compare the results of comparison between the two ground truth (LUKE with the one generated from experts) 
        // with Majority voting low fidelity ground truth
        public void CompareDifferencesWithMv(string differenceFile, string mvFile, string categoryFile, string outputFile)
        {
            var dif = File.ReadAllLines(differenceFile).ToCsvDictionary()
                .Select(i => new { Url = i["Url"], Label1E = i["Label1E"], Label1NE = i["Label1NE"], Label2E = i["Label2E"], Label2NE = i["Label2NE"] });
            
            var categories = File.ReadAllLines(categoryFile).ToCsvDictionary()
                .Select(i => new { Url = i["PictureURL"], Category = i["Category"] });

            var mv = File.ReadAllLines(mvFile).Select(l =>
            {
                var parts = l.Split(',');
                return new { Url = parts[0], Label1 = parts[1], Label2 = parts[2] };
            }).Join(categories, m => m.Url, c => c.Url, (m, c) => new { Url = m.Url, Label1 = m.Label1, Label2 = m.Label2, Categorty = c.Category });

            var output = dif.Join(mv, d => d.Url, m => m.Url, (d, m) => new { Diff = d, MV = m })
                .Select(i => string.Format("{0},{1},{2},{3},{4},{5},{6},{7}",
                    i.Diff.Url, i.MV.Categorty, i.Diff.Label1E, i.Diff.Label1NE, i.MV.Label1, i.Diff.Label2E, i.Diff.Label2NE, i.MV.Label2));

            var header = new string[] { "Url,Category,Label1E,Label1NE,Label1MV,Label2E,Label2NE,Label2MV" };
            File.WriteAllLines(outputFile, header.Concat(output));
        }
    
    }
}
